#include "SSD2832.h"
#include "../../DDIC/AllDDIC.h"
#include "fsmc.h"
#include "delay.h"
#include "debug.h"
#include "OuadSPI.h"
#include "../NCS8801/NCS8801.h"
#include "iic_current.h"
#include "mtp_pwm.h"

extern u8 nChannel_R;
extern u8 nChannel_G;
extern u8 nChannel_B;
//SSD2828----
u32 SSD2832RegPara=0; //供2832 32BIT 参数使用
u8 SSD2832RegC=0;
void SSD2828_initial_on(u8 signal_mode,u8 channel)
{
	for(i = 0;i<SSD28xxCode_count-1;i ++)	  //最后一位B7就不送了
	{
			if((u8)(SSD28xx_Code[i]>>16)==0xBB)
			{
				if(OLED.PHYMode == C_PHY)
				{
						SSD2828_W_Reg_u32(signal_mode,channel,0xBB,(0x0607<<16)+(u16)SSD28xx_Code[i]);   //BB[28]
						delay_ms(1);
						SSD2828_W_Reg(signal_mode,channel,0xD3,0x0040);//D3[6] CMD_BC broadcast the 2c/3c content from MIPITX0 to MIPITX1
						delay_ms(1);
				}
				else if(OLED.PHYMode == D_PHY)
				{
						SSD2828_W_Reg_u32(signal_mode,channel,0xBB,(0x1607<<16)+(u16)SSD28xx_Code[i]);
						delay_ms(1);
						SSD2828_W_Reg(signal_mode,channel,0xD3,0x0000);
						delay_ms(1);
				}
			}
			else
			{				
				if((i<SSD28xxCode_count-1)&&((SSD28xx_Code[i+1]>>16)==0))  //判断是否还有下一笔数据,且下一笔数据中reg位置数据为00
				{//判断是否还有下一笔数据,且下一笔数据中reg位置数据为00,此时把数据保存下即可
					SSD2832RegPara=(u16)SSD28xx_Code[i];
					SSD2832RegC=(u8)(SSD28xx_Code[i]>>16);
				}
				else
				{
					if(((SSD28xx_Code[i]>>16)==0))  //如果当前reg是00，则代表合并处理32bit的SSD2832 寄存器参数
					{
						SSD2832RegPara+=((u16)SSD28xx_Code[i])<<16;
						SSD2828_W_Reg_u32(signal_mode,channel,SSD2832RegC,SSD2832RegPara);
					}
					else  //如果不是则做普通处理
					{
						SSD2828_W_Reg(signal_mode,channel,(u8)(SSD28xx_Code[i]>>16),(u16)SSD28xx_Code[i]);
						delay_ms(1);
					}					
				}					
			}
	}
	delay_ms(20);
}

void SSD2832_initial_SCM(u8 signal_mode,u8 channel)
{
	for(i = 0;i<SSD28xx_SCM_Code_count;i++)	
	{
		  if(OLED.PHYMode == C_PHY)
			{
					SSD2828_W_SCM_Reg_u32(signal_mode ,channel, (u16)SSD28xx_SCM_Cmd[i] ,(u32)SSD28xx_SCM_Data[i]);
					delay_ms(1);
			}
	}
	delay_ms(20);
}

void Driver_ic_initial_on(u8 signal_mode,u8 channel)
{
	for(i=0;i<InitCode_count;i++)			
	{		
			SSD2828_W_Array(signal_mode,channel,InitCode_valid[i],0);
			delay_us(2);
	}
}

void SSD2828_signal_on(u8 signal_mode,u8 channel)
{
	for(i = 0;i<SSD28xxCode_count-1;i ++)	
	{
		if((u8)(SSD28xx_Code[i]>>16)==0xBB)
		{
			if(OLED.PHYMode == C_PHY)
			{
					SSD2828_W_Reg_u32(signal_mode,channel,0xBB,(0x0607<<16)+(u16)SSD28xx_Code[i]);   //BB[28]
					delay_ms(1);
					SSD2828_W_Reg(signal_mode,channel,0xD3,0x0040);//D3[6] CMD_BC broadcast the 2c/3c content from MIPITX0 to MIPITX1
					delay_ms(1);
			}
			else if(OLED.PHYMode == D_PHY)
			{
					SSD2828_W_Reg_u32(signal_mode,channel,0xBB,(0x1607<<16)+(u16)SSD28xx_Code[i]);
					delay_ms(1);
					SSD2828_W_Reg(signal_mode,channel,0xD3,0x0000);
					delay_ms(1);
			}
		}
		else
		{
			SSD2828_W_Reg(signal_mode,channel,(u8)(SSD28xx_Code[i]>>16),(u16)SSD28xx_Code[i]);
			delay_ms(1);
		}
	}
	delay_ms(50);
	for(i=0;i<InitCode_count;i++)			
	{		
			SSD2828_W_Array(signal_mode,channel,InitCode_valid[i],0);
			//NCS8801_I2CSend_Array_gamma(signal_mode,channel,InitCode_valid[i],0);
	}
//    FSMC_Pure_colour(BLACK); 
//    Load_done_HIGH;
    SSD2828_W_Reg(signal_mode,channel,(u8)(SSD28xx_Code[SSD28xxCode_count-1]>>16),(u16)SSD28xx_Code[SSD28xxCode_count-1]);
 #if InsertBlack == 1   
    delay_ms(5);
#endif
}
void SPI_signal_on(u8 SPI_Mode,u8 channel)
{
	for(i = 0;i<InitCode_count;i++)			
	{			
		if(((u8)InitCode_valid[i]==0x11)||((u8)InitCode_valid[i]==0x29))
		{
			SPI_Write_u8_Cmd(SPI_Mode,channel,(u8)InitCode_valid[i]);
			delay_ms(120);
		}
		else
		{
			SPI_Write_u8_Array(SPI_Mode,channel,(u8 *)InitCode_valid[i]);
			delay_ms(1);
		}
	}
}
void Set_eDP_reset(void)
{
    SSD_RESET_LOW;////reset  eDP biedge 
		delay_ms(100);
    SSD_RESET_HIGH;
	    delay_ms(15);
}
void Set_eDP_Powerdown(void)
{
    eDP_PWD_LOW;////powerdown  eDP biedge 
		delay_ms(100);
    eDP_PWD_HIGH;
	    delay_ms(15);
}

void Set_panel_reset(void)
{
		OLED_RESET_LOW;		//Panel RESET
    SSD_RESET_LOW;
    
		delay_ms(100);
		OLED_RESET_HIGH;
    SSD_RESET_HIGH;
	    delay_ms(15);
}
void Set_IO_status(u16 status)
{
    if((status&0x0001)==0x0001)////VDD ON
    {
        VCI_EN_HIGH;        ///bit 0--> VCI
    }
    else
    {
        VCI_EN_LOW;         ///bit 0--> VCI
    }
    
    if((status&0x0002)==0x0002)///VDDIO ON
    {
        VDDIO_EN_HIGH;      ///bit 1--> VDDIO	
    }
    else
    {
        VDDIO_EN_LOW;      ///bit 1--> VDDIO	
    }
    
    if((status&0x0004)==0x0004)///DVDD ON
    {
        DVDD_EN_HIGH;       ///bit 2--> DVDD	
    }
    else
    {
        DVDD_EN_LOW;       ///bit 2--> DVDD	
    }
    
    if((status&0x0008)==0x0008)///VBAT ON
    {
        RT8082_EN_HIGH;     ///bit 3--> VBAT
    }
    else
    {
        RT8082_EN_LOW;      ///bit 3--> VBAT
    }
    
    if((status&0x0010)==0x0010)///V3V3 ON
    {
        V3V3_EN_HIGH;       ///bit 4--> V3V3	
    }
    else
    {
        V3V3_EN_LOW;        ///bit 4--> V3V3	
    }
    if((status&0x0020)==0x0020)///V12V ON
    {
        V12V_EN_HIGH;       ///bit 5--> V12V 	
    }
    else
    {
        V12V_EN_LOW;        ///bit 5--> V12V 	
    }
    
    if((status&0x0080)==0x0080)///VPP ON
    {
        OTP_EN_HIGH;        ///bit 7--> VPP 	
    }
    else
    {
        OTP_EN_HIGH;        ///bit 7--> VPP 	
    }
    
    if((status&0x0100)==0x0100)///RESET
    {
        OLED_RESET_HIGH;       ///bit 8--> RESET 	
    }
    else
    {
        OLED_RESET_LOW;        ///bit 8--> RESET 	
    }
}

void Set_2828_reset(u8 Sig_Mode)
{	
		if(OLED.PHYMode == D_PHY) //00
		{
				TEST_MODE0_DPHY;  //TSET_MODE0 1：MIPI DHPY OUTPUT is selected
		}
		else if(OLED.PHYMode == C_PHY) //01
		{
				TEST_MODE0_CPHY;   //TSET_MODE0 0：MIPI CHPY OUTPUT is selected
		}
    if(Sig_Mode == Video_Mode)
    {
        IF_Sel1_Video;  
    }
    else if(Sig_Mode == CMD_Mode)
    {
        IF_Sel1_Cmd;
    }

        SSD_RESET_LOW;			//SSD2832 RESET
		OLED_RESET_LOW;		//Panel RESET
		delay_ms(100);
		SSD_RESET_HIGH;	
		OLED_RESET_HIGH;
        delay_ms(15); 
}


void SSD2828_W_Cmd(u8 SigMode ,u8 channel,u8 cmd)
{
    if(SigMode == Video_Mode)
    {
        SPI_Write_u8_Cmd(SPI3_Mode,channel,cmd);
    }
    else if(SigMode == CMD_Mode)
    {
        MCU_2832_write_CMD(channel,cmd);
    }
}

void SSD2828_W_Cmd_NOCS(u8 cmd)
{
	MCU_2832_write_CMD_NOCS(cmd);
}
    

void SSD2828_W_Data(u8 SigMode ,u8 channel,u16 Value)
{
    if(SigMode == Video_Mode)
    {
        SPI_Write_u8_Data(SPI3_Mode,channel,Value);
    }
    else if(SigMode == CMD_Mode)
    {
        MCU_2832_Write_Data(channel,Value);
    }
}

u16 SSD2828_R_Data(u8 SigMode ,u8 channel)
{
    u16  data_code;
    if(SigMode == Video_Mode)
    {
        data_code = SPI3_Read_u8_Data(channel);
    }
    else if(SigMode == CMD_Mode)
    {
        data_code = MCU_2832_Read_Data(channel);
    }
    return data_code;
}

void SSD2828_W_SCM_Reg_u32(u8 SigMode ,u8 channel, u16 Cmd ,u32 Value) //SSD2832 Send SCM reg使用
{  
    SSD2828_W_Cmd(SigMode ,channel,0xE0); //SCM
    if(SigMode == Video_Mode)
    {
        SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&Cmd));
        SSD2828_W_Data(SigMode ,channel,(u8)(Cmd>>8));	
        SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&Value));
        SSD2828_W_Data(SigMode ,channel,(u8)(Value>>8));	
        SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&(Value>>16)));
        SSD2828_W_Data(SigMode ,channel,(u8)(Value>>24));					
    }
    else if(SigMode == CMD_Mode)
    {
		#ifdef SSD_Command_16	
		SSD2828_W_Data(SigMode ,channel,Cmd);
        SSD2828_W_Data(SigMode ,channel,Value);
        SSD2828_W_Data(SigMode ,channel,Value>>16);			
		#else
			SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&Cmd));
			SSD2828_W_Data(SigMode ,channel,(u8)(Cmd>>8));
			SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&Value));
			SSD2828_W_Data(SigMode ,channel,(u8)(Value>>8));
			SSD2828_W_Data(SigMode ,channel,(u8)(Value>>16));
			SSD2828_W_Data(SigMode ,channel,(u8)(Value>>24));				
		#endif
    }
}

void SSD2828_W_Reg_u32(u8 SigMode ,u8 channel,u8 Reg, u32 Value) //SSD2832初始化使用
{  
    SSD2828_W_Cmd(SigMode ,channel,Reg);
    if(SigMode == Video_Mode)
    {
        SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&Value));
        SSD2828_W_Data(SigMode ,channel,(u8)(Value>>8));	
        SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&(Value>>16)));
        SSD2828_W_Data(SigMode ,channel,(u8)(Value>>24));					
    }
    else if(SigMode == CMD_Mode)
    {
		#ifdef SSD_Command_16	
        SSD2828_W_Data(SigMode ,channel,Value);
        SSD2828_W_Data(SigMode ,channel,Value>>16);			
		#else
	    SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&Value));
	    SSD2828_W_Data(SigMode ,channel,(u8)(Value>>8));
			SSD2828_W_Data(SigMode ,channel,(u8)(Value>>16));
			SSD2828_W_Data(SigMode ,channel,(u8)(Value>>24));				
		#endif
    }
}

void SSD2828_W_Reg(u8 SigMode ,u8 channel,u8 Reg, u16 Value)
{  
  if(eDP_ncs8805 == 1)
	{
		NCS8801_I2CSend(Reg,((Value&0xFF00)>>8),Value);
//        SSD2828_W_Array(SigMode,channel,buffer,2);
	}
	else
	{
	SSD2828_W_Cmd(SigMode ,channel,Reg);
    if(SigMode == Video_Mode)
    {
        SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&Value));
        SSD2828_W_Data(SigMode ,channel,(u8)(Value>>8));
    }
    else if(SigMode == CMD_Mode)
    {
		#ifdef SSD_Command_16	
        SSD2828_W_Data(SigMode ,channel,Value);
		#else
	    SSD2828_W_Data(SigMode ,channel,(u8)(0x00ff&Value));
	    SSD2828_W_Data(SigMode ,channel,(u8)(Value>>8));
		#endif
    }
	}
}


u32 SSD2828_R_Reg(u8 SigMode ,u8 channel,u8 Reg)
{
    u32 data;
    SSD2828_W_Cmd(SigMode ,channel,Reg);
    if(SigMode == Video_Mode)
    {
        SSD2828_W_Cmd(SigMode ,channel,0xFA);
        data= (u32)SSD2828_R_Data(SigMode ,channel);
        data= ((u32)SSD2828_R_Data(SigMode ,channel)<<8)|data;
				SSD2828_W_Cmd(SigMode ,channel,0xFA);
				data= ((u32)SSD2828_R_Data(SigMode ,channel)<<16)|data;
				data= ((u32)SSD2828_R_Data(SigMode ,channel)<<24)|data;
    }

    else if(SigMode == CMD_Mode)
    {    
		#ifdef SSD_Command_16	
        data = SSD2828_R_Data(SigMode ,channel);
		#else
        data=(u16)SSD2828_R_Data(SigMode ,channel);
        data= data|(((u16)SSD2828_R_Data(SigMode ,channel))<<8);
		#endif	
    }
	return data;
}


u16 SSD2828_R_Reg_Flow(u8 SigMode ,u8 channel)
{
    u16 data;  
	#ifdef SSD_Command_16	
	data = SSD2828_R_Data(SigMode ,channel);
	#else
	data=(u16)SSD2828_R_Data(SigMode ,channel);
	data= data|(((u16)SSD2828_R_Data(SigMode ,channel))<<8);
	#endif	
	return data;
}


extern u16 MipiCommandModeSelect;
void SSD2828_W_Array(u8 SigMode ,u8 channel,u8 para[],u8 offerset)
{
	u8 i,r=0,g=0,b=0;u8 tep;	
	if((para[1+offerset]==0xff)&&(para[2+offerset]==0xff)&&(para[3+offerset]==0xff))
	{	//代码中断延时函数, by zangqiang 201712225
		if((para[4+offerset]>0)&&(para[4+offerset]<=0xff))
		{
			delay_ms(para[4+offerset]);
		}
	}
    else if((para[1+offerset]==0xff)&&(para[2+offerset]==0xff)&&(para[3+offerset]==0xFD))
	{
        /////power control
        Set_IO_status((para[4+offerset]<<8)+para[5+offerset]);
    }
	else if((para[1+offerset]==0xff)&&(para[2+offerset]==0xff)&&(para[3+offerset]==0xfc))
	{
			//I2C1Write (u8 ucDeviceAddr, u8 unDataLength,u8 *buf);
				I2C1Write(para[4+offerset],para[0+offerset]-4,para+5+offerset);
				//Debug_lrg[0]=para[4+offerset];
				//Debug_lrg[1]=para[0+offerset]-4;
				//Debug_lrg[2]=para[5+offerset];
				//Debug_lrg[3]=para[6+offerset];
	}
    else if((para[1+offerset]==0xFF)&&(para[2+offerset]==0xFF)&&(para[3+offerset]==0xFA))
	{
        //SAMPLE code  : 0XFF,0XFF,0XFA,0X02,      0X03,     0X80,         0X6F,    0X09
        //////                           Channel,  length,  slave address, reg,    data
				IIC_xxBIT_1v8_Array(para[4+offerset],para[6+offerset],para[0+offerset]-6,para+7+offerset);
	}
    else if((para[1+offerset]==0xFF)&&(para[2+offerset]==0xFF)&&(para[3+offerset]==0xFB))
	{
        //SAMPLE code  : 0XFF,0XFF,0XFB,0X02,      0X03,     0X80,         0X6F,   0X01   
        //////                           Channel,  length,  slave address, reg,  read_back_num
//				IIC_xxBIT_1v8_Array(para[4+offerset],para[6+offerset],para[0+offerset]-6,para+7+offerset);
        Vx_eDP_IIC_Read_1V8(SigMode,channel,buffer);
	}
    else if((para[1+offerset]==0xFF)&&(para[2+offerset]==0xFF)&&(para[3+offerset]==0xF9))//8bit spi send
	{
        //SAMPLE code  : 0XFF,0XFF,0XF9,0X50,      0X00,     0X13,         0X34,    0X00
        //////                           address,  addr_h,  addr_L       , data,    dummy
        if(para[4+offerset] == 0x50)
        {
            SPI_Panel_DDIC(para[4+offerset],para[5+offerset],para[6+offerset],para[7+offerset],para[8+offerset]);
        }
        else if(para[4+offerset] == 0x05)
        {
            SPI_Panel_DDIC_Read(para[4+offerset],para[5+offerset],para[6+offerset],para[7+offerset],para[8+offerset]);
        }
        else
        {
            SPI_Panel_DDIC(para[4+offerset],para[5+offerset],para[6+offerset],para[7+offerset],para[8+offerset]);
        }
	}
    else if((para[1+offerset]==0xFF)&&(para[2+offerset]==0xFF)&&(para[3+offerset]==0xF8))///32bit spi send
	{
        if(para[offerset+4]==0xDE)///SPI 32bit write  for SD3106
        {
            SPI_Panel_DDIC_long(para[offerset]-3,para,offerset+4);
        }
        else if(para[offerset+4]==0xDD)///SPI 32bit read  for SD3106
        {
            SPI_Panel_DDIC_long_read(para[offerset]-3,para,offerset+4,para);
        }
        else////SPI send for other IC use
        {
            SPI_Panel_DDIC_long(para[offerset]-3,para,offerset+4);
        }
    }
    else if((para[1+offerset]==0xFF)&&(para[2+offerset]==0xFF)&&(para[3+offerset]==0xF7))//16bit spi send 
	{
        ////32bit  read
        
        
        //16bit  void  ,bak 
        SPI_Panel_DDIC_long_16bit_alan(para[offerset]-3,para,offerset+4);
        //SPI_Panel_DDIC_long_16bit(para[offerset]-3,para,offerset+4);
    }
	else if((para[1+offerset]==0xff)&&(para[2+offerset]==0xfE)&&(para[3+offerset]==0xfd))
	{	//识别上位机发送的29/39以切换mipi数据包格式
		//if((para[4+offerset]>0)&&(para[4+offerset]<=0xff))
		{
			tep=(para[4+offerset]);   //(29/39.....)
			if(tep==0x13)  //LP_Gerneric_Short_Write.Generic Short Write, 1 parameter
			{MipiCommandModeSelect=LP_Gerneric_Short_Write; }
//			else if((tep&0x0f)==0x09)//HS_Gerneric_Short_Write
//			{MipiCommandModeSelect=HS_Gerneric_Short_Write;}
//			else if((tep&0x0f)==0x0a)//LP_DCS_Short_Write
//			{MipiCommandModeSelect=LP_DCS_Short_Write;}
//			else if((tep&0x0f)==0x0b)//HS_DCS_Short_Write	
//			{MipiCommandModeSelect=HS_DCS_Short_Write;}	
			else if(tep==0x29)//LP_Gerneric_Long_Write
			{MipiCommandModeSelect=LP_Gerneric_Long_Write;}
//			else if((tep&0x0f)==0x0d)//HS_Gerneric_Long_Write
//			{MipiCommandModeSelect=HS_Gerneric_Long_Write;}
			else if(tep==0x39)//LP_DCS_Long_Write
			{MipiCommandModeSelect=LP_DCS_Long_Write;}
//			else if((tep&0x0f)==0x0f)//HS_DCS_Long_Write	
//			{MipiCommandModeSelect=HS_DCS_Long_Write;}
			SSD2828_W_Reg(SigMode,channel,0xB7,MipiCommandModeSelect);
			delay_ms(5);
			//MipiCommandModeSelect=HS_DCS_Long_Write;SSD2828_W_Reg(SigMode,channel,0xB7,MipiCommandModeSelect);
		}		
	}
	else if((para[1+offerset]==0xff)&&(para[2+offerset]==0xfE)&&(para[3+offerset]==0x29))
	{	//海思专用代码解析--数据包格式： FF,FE,29,0xFF,0xXX,0xXX,0xXX,0x39,0xXX,0xXX,0xXX,0xXX,0xXX
		//tep=(para[4+offerset]);   //
		
		MipiCommandModeSelect=LP_Gerneric_Long_Write;
		SSD2828_W_Reg(SigMode,channel,0xB7,MipiCommandModeSelect);
		delay_ms(5);
		
		SSD2828_W_Reg(SigMode ,channel,0xBC, 4);
		SSD2828_W_Reg(SigMode ,channel,0xBD, 0x0000);
		SSD2828_W_Cmd(SigMode ,channel,0xBF);	
		if(SigMode == Video_Mode)
		{    
			SSD2828_W_Data(SigMode ,channel,para[4+offerset]);
			SSD2828_W_Data(SigMode ,channel,para[5+offerset]);		
			SSD2828_W_Data(SigMode ,channel,para[6+offerset]);
			SSD2828_W_Data(SigMode ,channel,para[7+offerset]);	
					
		}
		else if(SigMode == CMD_Mode)
		{  
			#ifdef SSD_Command_16	
			SSD2828_W_Data(SigMode ,channel,(para[5+offerset]<<8)+para[4+offerset]);
			SSD2828_W_Data(SigMode ,channel,(para[7+offerset]<<8)+para[6+offerset]);
			
			#else
//			SSD2828_W_Data(SigMode ,channel,para[1+offerset]);
//			for(i = 1; i < para[0+offerset]; i++)
//			{
//				SSD2828_W_Data(SigMode ,channel,para[i+1+offerset]);
//			}
			#endif
		}		
		
		MipiCommandModeSelect=LP_DCS_Long_Write;
		SSD2828_W_Reg(SigMode,channel,0xB7,MipiCommandModeSelect);
		delay_ms(5);
		SSD2828_W_Reg(SigMode ,channel,0xBC, 5);
		SSD2828_W_Reg(SigMode ,channel,0xBD, 0x0000);
		SSD2828_W_Cmd(SigMode ,channel,0xBF);	
		
		if(SigMode == Video_Mode)
		{    
			SSD2828_W_Data(SigMode ,channel,para[9+offerset]);
			SSD2828_W_Data(SigMode ,channel,para[10+offerset]);		
			SSD2828_W_Data(SigMode ,channel,para[11+offerset]);
			SSD2828_W_Data(SigMode ,channel,para[12+offerset]);	
			SSD2828_W_Data(SigMode ,channel,para[13+offerset]);				
		}
		else if(SigMode == CMD_Mode)
		{  
			#ifdef SSD_Command_16	
			SSD2828_W_Data(SigMode ,channel,(para[10+offerset]<<8)+para[9+offerset]);
			SSD2828_W_Data(SigMode ,channel,(para[12+offerset]<<8)+para[11+offerset]);
			SSD2828_W_Data(SigMode ,channel,                       para[13+offerset]);
			
			#else
//			SSD2828_W_Data(SigMode ,channel,para[1+offerset]);
//			for(i = 1; i < para[0+offerset]; i++)
//			{
//				SSD2828_W_Data(SigMode ,channel,para[i+1+offerset]);
//			}
			#endif
		}		
	}
	else if((para[1+offerset]==0xff)&&(para[2+offerset]==0xff)&&(para[3+offerset]==0xfe))
	{ //通过命令方式送纯色画面
		{
			r=para[4+offerset];		
			g=para[5+offerset];		
			b=para[6+offerset];
		}
		if(OLED.SigMode == Video_Mode)
		{
			FSMC_Pure_colour((u32)(r<<16)|((u32)(g<<8)|b));
            Load_done_HIGH;
		}
		else if(OLED.SigMode == CMD_Mode)           //Command 模式
		{
			SSD2828_W_Reg(OLED.SigMode,CS1,0xB7,HS_B7_Data);
			SSD2828_W_RAM_Pic(OLED.pixel_clk,OLED.SigMode,CS1,OLED.H_pixel,OLED.V_pixel,r,g,b);
			SSD2828_W_Reg(OLED.SigMode,CS1,0xB7,LP_B7_Data);
		}
	}
	else
	{
//		SSD2828_W_Reg(SigMode ,channel,0xBC, para[0+offerset]);
//		SSD2828_W_Reg(SigMode ,channel,0xBD, 0x0000);
//		SSD2828_W_Cmd(SigMode ,channel,0xBF);	
		
		if(SigMode == Video_Mode)
		{    
//            NCS8801_I2CSend_Array(SigMode ,channel, para[0+offerset],offerset);
//				NCS8801_I2CSend_Array_gamma(SigMode ,channel, para[0+offerset],offerset);
//			SSD2828_W_Data(SigMode ,channel,para[1+offerset]);
//			for(i = 1; i < para[0+offerset]; i++)
			
            {
                NCS8801_I2CStart_device(2);

                //for(i = 1; i <= ucIndex-0; i++)
                for(i = 0; i < para[0+offerset]-0; i++)
                {
                    tep = para[1+i+offerset];
                    if(NCS8801_I2CSendByte_device(2,tep) == ACK)
                    {;}
                }

                  NCS8801_I2CStop_device(2);
            }
//            {
//				NCS8801_I2CStart();


//            for(i = 0; i < para[0+offerset]-0; i++)
//            {
//                tep = para[1+i+offerset];
//                if(NCS8801_I2CSendByte(tep) == ACK)
//                {;}
//            }

//            NCS8801_I2CStop();
//				//SSD2828_W_Data(SigMode ,channel,para[i+1+offerset]);
//			}
		}
		else if(SigMode == CMD_Mode)
		{  
			#ifdef SSD_Command_16	
			SSD2828_W_Data(SigMode ,channel,(para[2+offerset]<<8)+para[1+offerset]);
			for(i = 0; i < (((para[0+offerset]-2)/2)+((para[0+offerset]-2)%2)); i++)
			{
				SSD2828_W_Data(SigMode ,channel,(para[4+i*2+offerset]<<8)+para[3+i*2+offerset]);
			}
			#else
			SSD2828_W_Data(SigMode ,channel,para[1+offerset]);
			for(i = 1; i < para[0+offerset]; i++)
			{
				SSD2828_W_Data(SigMode ,channel,para[i+1+offerset]);
			}
			#endif
		}
		else if((SigMode == SPI3_Mode) || (SigMode == SPI4_Mode))
		{
			GenW_PANEL_SPI_Write_code(SigMode,channel,para);
		}
		else if(SigMode==QuadSPI_Mode)
		{
			OSPI_Write_u8_Array(SigMode,channel , para,offerset);

		}
		if((para[0+offerset] == 1)&&(para[1] == 0x11))
		delay_ms(120); 		
	 }		
}

u8 SSD2828_W_Array_SPI(u8 SigMode, u8 channel, u8 para[], u8 offerset){
    u8 rec = 0;
    //Example: FF,FF,F9,05,20,20,00,00
    //byte write: 0x50 + addr_H + addr_L + wData + Dummy
    //byte read:  0x05 + addr_H + addr_L + Dummy + rData
    if((para[1+offerset]==0xFF) && (para[2+offerset]==0xFF) && (para[3+offerset]==0xF9) && (para[4+offerset] == 0x05))     
        rec = SPI_Panel_DDIC_Read(para[4+offerset], para[5+offerset], para[6+offerset], para[7+offerset], para[8+offerset]);
   
    return rec;
}

u32 Data_Num = 0;
u32 HalfData_Num=0;
u32 Data_Numdivided6=0;
void UsbBMPData2FPGAbyFSMC(u8* buffer)
{
  	u32 i;
    {
		for(i = 0;i<(USB_ReceivedCount);i+=2)
		{
			Write_DATA(buffer[i]+(buffer[(i)+1]<<8));
		}        
    }    
}


void SSD2828_W_RAM_buffer_565bits_part(float pclk,u8 SigMode ,u8* buffer ,u16 length,u8  multiple ,u8 DisMode)
{
  	u32 i;
	u16 RGB565_Data;
    Data_Num = length*multiple*3;
	Data_Numdivided6=Data_Num/3;

	#ifdef SSD_Command_16
	for(i=0;i<(Data_Numdivided6);i++)
	{
		RGB565_Data = ((buffer[i*3]&0xf8)<<8) | ((buffer[i*3+1]&0xfc)<<3) | (buffer[i*3+2]>>3);			
	//	RGB565_Data = ((buffer[i*3]&0x1F)<<11) | ((buffer[i*3+2]&0xfc)<<3) | ((buffer[i*3+1]<<5)>>3);		
		Write_DATA(RGB565_Data);			
	}
	#else	
	for(i=0;i<Data_Num/3;i++)
	{
		Write_DATA(buffer[i*3+2]);
		Write_DATA(buffer[i*3+1]);
		Write_DATA(buffer[i*3]);          
	}
	#endif 
}

int temmp=0;
void SSD2828_W_RAM_buffer_8bits_part(float pclk,u8 SigMode ,u8* buffer ,u16 length,u8  multiple ,u8 DisMode)
{
  	u32 i;
	u32 delay_time=(pclk < 50) ? 50 : 0;	
    Data_Num = length*multiple*3;
	HalfData_Num=Data_Num/2;
	Data_Numdivided6=Data_Num/6;
//    if(SigMode == Video_Mode)
    {
        if(DisMode == 0)
        {
            for(i = 0;i<HalfData_Num;i++)
            {
                Write_DATA(buffer[i<<1]*nChannel_B+(buffer[(i<<1)+1]*nChannel_G<<8));
                delay_6ns(delay_time);i++;
				Write_DATA(buffer[i<<1]*nChannel_R+(buffer[(i<<1)+1]*nChannel_B<<8));
				delay_6ns(delay_time);i++;
				Write_DATA(buffer[i<<1]*nChannel_G+(buffer[(i<<1)+1]*nChannel_R<<8));
				delay_6ns(delay_time);
                
            } 
        }
		else if(DisMode == 1) 
        {                        
            while(Data_Num > 0)
            {
                for(i=0;i<length/2;i++)
                {
					Write_DATA(buffer[i*6]+(buffer[i*6+1]<<8));
					Write_DATA(buffer[i*6+2]+(buffer[i*6+3]<<8));
					Write_DATA(buffer[i*6+4]+(buffer[i*6+5]<<8));
					Data_Num-=6; 
                }                                       
            }
        }
 
    }
//    else if(SigMode == CMD_Mode)
//    {
//		#ifdef SSD_Command_16
//        for(i=0;i<(Data_Numdivided6);i++)
//        {
//            Write_DATA(((buffer[i*6+1]*nChannel_G)<<8)+buffer[i*6+2]*nChannel_R);	
//            Write_DATA(((buffer[i*6+5]*nChannel_R)<<8)+buffer[i*6]*nChannel_B);	
//            Write_DATA(((buffer[i*6+3]*nChannel_B)<<8)+buffer[i*6+4]*nChannel_G);						
//        }
//		#else	
//        for(i=0;i<Data_Num/3;i++)
//        {
//            Write_DATA(buffer[i*3+2]);
//            Write_DATA(buffer[i*3+1]);
//            Write_DATA(buffer[i*3]);          
//        }
//		#endif
//    }   
}
void SSD2828_W_RAM_Pic(float pclk,u8 SigMode ,u8 channel ,u16 H_Pix,u16 V_Pix,u8 R ,u8 G,u8  B )
{
  	u32 i;
    u16 BC_Data,BD_Data,BE_Data;
    BC_Data = (u16)(H_Pix*V_Pix*3);
    BD_Data = (u16)((H_Pix*V_Pix*3)>>16);
	if(H_Pix*3<=8192)
		BE_Data = (u16)(H_Pix*3);//
	else
		BE_Data = 8184;//			
    
    SSD2828_W_Reg(SigMode ,channel,0xBC,BC_Data); 
    SSD2828_W_Reg(SigMode ,channel,0xBD,BD_Data); 
    SSD2828_W_Reg(SigMode ,channel,0xBE,BE_Data);                         

    SSD2828_W_Cmd(SigMode ,channel,0xBF);
    SSD2828_W_Cmd(SigMode ,channel,0X2C);   
    SPI_CS_Select(channel,0);
	#ifdef SSD_Command_16
    for(i=0;i<H_Pix*V_Pix/2;i++)
    {
        Write_DATA((G<<8) + R);
        //delay_6ns(5);
        Write_DATA((R<<8) + B);
        //delay_6ns(5);
        Write_DATA((B<<8) + G);
        //delay_6ns(5);
    }
	#else
	for(i=0;i<H_Pix*V_Pix;i++)
	{
        Write_DATA(R);
        Write_DATA(G);
        Write_DATA(B); 
	}
	#endif
    SPI_CS_Select(channel,1);
}


void SSD2828_W_LOGIC_Pic(float pclk,u8 SigMode ,u8 channel ,u16 H_Pix,u16 V_Pix,u16 PIC_NUM)
{
  	u32 i;
    u16 BC_Data,BD_Data,BE_Data;
    BC_Data = (u16)(H_Pix*V_Pix*3);
    BD_Data = (u16)((H_Pix*V_Pix*3)>>16);
		if(H_Pix*3<=8192)
			BE_Data = (u16)(H_Pix*3);//
		else
			BE_Data = 8184;//			
    
    SSD2828_W_Reg(SigMode ,channel,0xBC,BC_Data); 
    SSD2828_W_Reg(SigMode ,channel,0xBD,BD_Data); 
    SSD2828_W_Reg(SigMode ,channel,0xBE,BE_Data);                         

    SSD2828_W_Cmd(SigMode ,channel,0xBF);
    SSD2828_W_Cmd(SigMode ,channel,0X2C);   
    SPI_CS_Select(channel,0);
	MCU_LOGIC_EN_LOW;
	delay_us(4);
	write_cmd(0x6789);						//将OLED时序数据发送到FPGA
	delay_us(4);
	write_cmd((0x4<<8)|PIC_NUM);
	delay_us(4);
	write_cmd(0x9876);
	delay_us(4);
		
    for(i=0;i<H_Pix*V_Pix;i++)
    {
        delay_6ns(10);
	  }
		MCU_LOGIC_EN_HIGH;
    SPI_CS_Select(channel,1);
}


void SSD2828_W_CMD_EDIT_LOGIC_Pic(float pclk,u8 SigMode ,u8 channel ,u16 H_Pix,u16 V_Pix,u16 PIC_NUM,u32 Color_M,u32 Color_L,u16 X0,u16 X1,u16 Y0,u16 Y1,u16 R0)
{
  	u32 i;
    u16 BC_Data,BD_Data,BE_Data;
    BC_Data = (u16)(H_Pix*V_Pix*3);
    BD_Data = (u16)((H_Pix*V_Pix*3)>>16);
		if(H_Pix*3<=8192)
			BE_Data = (u16)(H_Pix*3);//
		else
			BE_Data = 8184;//			
    
    SSD2828_W_Reg(SigMode ,channel,0xBC,BC_Data); 
    SSD2828_W_Reg(SigMode ,channel,0xBD,BD_Data); 
    SSD2828_W_Reg(SigMode ,channel,0xBE,BE_Data);                         

    SSD2828_W_Cmd(SigMode ,channel,0xBF);
    SSD2828_W_Cmd(SigMode ,channel,0X2C);   
    SPI_CS_Select(channel,0);
	MCU_LOGIC_EN_LOW;
	delay_us(4);			
	write_cmd(0x1122);			delay_us(4);					//将OLED时序数据发送到FPGA
	write_cmd((0x4<<8)|PIC_NUM);		delay_us(4);
	write_cmd((u16)(Color_M>>8));		delay_us(4);	
	write_cmd((u16)(((Color_M&0x0000ff)<<8)|((Color_L&0xff0000)>>16)));		delay_us(4);	
	write_cmd((u16)(Color_L&0x00ffff));		delay_us(4);	
	write_cmd(X0);		delay_us(4);
	write_cmd(X1);		delay_us(4);
	write_cmd(Y0);		delay_us(4);
	write_cmd(Y1);		delay_us(4);	
	write_cmd(R0);		delay_us(4);		
	write_cmd(0x2211);	delay_us(4);					
    for(i=0;i<H_Pix*V_Pix;i++)
    {
        delay_6ns(10);
	}
	MCU_LOGIC_EN_HIGH;
    SPI_CS_Select(channel,1);
}

void SSD2828_W_CMD_LOGIC_Pure_Color(float pclk,u8 SigMode ,u8 channel ,u16 H_Pix,u16 V_Pix,u32 Color)
{
  	u32 i;
    u16 BC_Data,BD_Data,BE_Data;
    BC_Data = (u16)(H_Pix*V_Pix*3);
    BD_Data = (u16)((H_Pix*V_Pix*3)>>16);
		if(H_Pix*3<=8192)
			BE_Data = (u16)(H_Pix*3);//
		else
			BE_Data = 8184;//			
    
    SSD2828_W_Reg(SigMode ,channel,0xBC,BC_Data); 
    SSD2828_W_Reg(SigMode ,channel,0xBD,BD_Data); 
    SSD2828_W_Reg(SigMode ,channel,0xBE,BE_Data);                         

    SSD2828_W_Cmd(SigMode ,channel,0xBF);
    SSD2828_W_Cmd(SigMode ,channel,0X2C);   
    SPI_CS_Select(channel,0);
	MCU_LOGIC_EN_LOW;
	delay_us(4);
	write_cmd(0x5678);						//将OLED时序数据发送到FPGA
	delay_us(4);
	write_cmd((0x4<<8)|((Color&0xff0000)>>16));
	delay_us(4);
	write_cmd((u16)(Color&0x00ffff));
	delay_us(4);
	write_cmd(0x8765);
	delay_us(4);
		
    for(i=0;i<H_Pix*V_Pix;i++)
    {
        delay_6ns(10);
	}
	MCU_LOGIC_EN_HIGH;
    SPI_CS_Select(channel,1);
}

void SSD2828_Set_Window(u8 SigMode ,u8 channel,u16 H_Start,u16 H_End,u16 V_Start,u16 V_End)
{
    u8 Window_Table[2][6];
    
    Window_Table[0][0]=0x05;
    Window_Table[0][1]=0x2A;
    Window_Table[0][2]=H_Start>>8;
    Window_Table[0][3]=H_Start;
    Window_Table[0][4]=(H_End-1)>>8;
    Window_Table[0][5]=(H_End-1);

    Window_Table[1][0]=0x05;
    Window_Table[1][1]=0x2B;
    Window_Table[1][2]=V_Start>>8;
    Window_Table[1][3]=V_Start;
    Window_Table[1][4]=(V_End-1)>>8;
    Window_Table[1][5]=(V_End-1);

    SSD2828_W_Array(SigMode,channel,Window_Table[0],0);
    SSD2828_W_Array(SigMode,channel,Window_Table[1],0);  
}



